
package com.hlkj.pay.app.merchant.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.provider.Ip2regionProvider;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.executor.ExtensionExecutor;
import com.hlkj.framework.extension.scenario.BizScenario;
import com.hlkj.pay.app.merchant.ext.*;
import com.hlkj.pay.common.constants.MqConstant;
import com.hlkj.pay.config.ExtRocketMQTemplate;
import com.hlkj.pay.infrastructure.model.common.RequestLogDO;

import cn.hutool.extra.servlet.ServletUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.ip2region.core.IpInfo;

/**
 * @author HlpayTeam
 * @date 2024/09/29 16:44
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CommonChannelCallHandler {

    private final ExtensionExecutor extensionExecutor;

    private final ExtRocketMQTemplate extRocketMQTemplate;

    private final Ip2regionProvider ip2regionProvider;

    /**
     * 返回信息处理
     * 
     * @param channelCode
     * @param providerCode
     * @param requestId
     * @param serviceName
     * @param callBackBody
     * @param thirdParams
     * @param commonResult
     * @return
     */
    public String processAccessLogAndResponse(String channelCode, String providerCode, String requestId, String serviceName, String callBackBody, Object thirdParams,
                                              CommonResult commonResult) {
        // 不同渠道返回信息转换
        String response = extensionExecutor.execute(ChannelMerchantAccessExtPt.class, BizScenario.valueOf(channelCode), ex -> ex.callBackResponse(commonResult));
        // 记录请求日志
        // sendRequestMessage(channelCode, providerCode, requestId, serviceName, callBackBody, thirdParams, response);
        return response;
    }

    /**
     * 返回信息处理
     * 
     * @param channelCode
     * @param commonResult
     * @return
     */
    public String processReportLogAndResponse(String channelCode, String providerCode, String requestId, String callBackBody, CommonResult commonResult) {
        // 不同渠道返回信息转换
        String response = extensionExecutor.execute(ChannelMerchantReportExtPt.class, BizScenario.valueOf(channelCode), ex -> ex.callBackResponse(commonResult));
        String serviceName = channelCode + "_report_callback";
        // 记录请求日志
        // sendRequestMessage(channelCode, providerCode, requestId, serviceName, callBackBody, null, response);
        return response;
    }

    /**
     * 返回信息处理
     *
     * @param channelCode
     * @param commonResult
     * @return
     */
    public String processSettleLogAndResponse(String channelCode, String providerCode, String requestId, String callBackBody, CommonResult commonResult) {
        // 不同渠道返回信息转换
        String response = extensionExecutor.execute(ChannelMerchantAccessExtPt.class, BizScenario.valueOf(channelCode), ex -> ex.callBackResponse(commonResult));

        String serviceName = channelCode + "_order_settle_callback";
        // 记录请求日志
        // sendRequestMessage(channelCode, providerCode, requestId, serviceName, callBackBody, null, response);
        return response;
    }

    /**
     * 返回信息处理
     *
     * @param channelCode
     * @param commonResult
     * @return
     */
    public String processPayLogAndResponse(String channelCode, String providerCode, String requestId, String callBackBody, CommonResult commonResult) {
        // 不同渠道返回信息转换
        String response = extensionExecutor.execute(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(channelCode), ex -> ex.callBackResponse(commonResult));
        String serviceName = channelCode + "_order_pay_callback";
        // 记录请求日志
        // sendRequestMessage(channelCode, providerCode, requestId, serviceName, callBackBody, null, response);
        return response;
    }
    /**
     * 返回信息处理
     *
     * @param channelCode
     * @param commonResult
     * @return
     */
    public String processRefundLogAndResponse(String channelCode, String providerCode, String requestId, String callBackBody, CommonResult commonResult) {
        // 不同渠道返回信息转换
        String response = extensionExecutor.execute(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(channelCode), ex -> ex.callBackResponse(commonResult));
        String serviceName = channelCode + "_order_refund_callback";
        // 记录请求日志
        // sendRequestMessage(channelCode, providerCode, requestId, serviceName, callBackBody, null, response);
        return response;
    }

    /**
     * 返回信息处理
     *
     * @param channelCode
     * @param commonResult
     * @return
     */
    public String processWithdrawLogAndResponse(String channelCode, String providerCode, String requestId, String callBackBody, CommonResult commonResult) {
        // 不同渠道返回信息转换
        String response = extensionExecutor.execute(ChannelMerchantWithdrawExtPt.class, BizScenario.valueOf(channelCode), ex -> ex.callBackResponse(commonResult));
        String serviceName = channelCode + "_order_withdraw_callback";
        // 记录请求日志
        // sendRequestMessage(channelCode, providerCode, requestId, serviceName, callBackBody, null, response);
        return response;
    }

    /**
     * 返回信息处理
     *
     * @param channelCode
     * @param commonResult
     * @return
     */
    public String processTransferLogAndResponse(String channelCode, String providerCode, String requestId, String callBackBody, CommonResult commonResult) {
        // 不同渠道返回信息转换
        String response = extensionExecutor.execute(ChannelMerchantTransferExtPt.class, BizScenario.valueOf(channelCode), ex -> ex.callBackResponse(commonResult));
        String serviceName = channelCode + "_order_transfer_callback";
        // 记录请求日志
        // sendRequestMessage(channelCode, providerCode, requestId, serviceName, callBackBody, null, response);
        return response;
    }

    public String processComplaintLogAndResponse(String channelCode, CommonResult commonResult) {
        // 不同渠道返回信息转换
        String response = extensionExecutor.execute(ChannelMerchantAccessExtPt.class, BizScenario.valueOf(channelCode), ex -> ex.callBackResponse(commonResult));
        String serviceName = channelCode + "_order_complaint_callback";
        // 记录请求日志
        // sendRequestMessage(channelCode, providerCode, requestId, serviceName, callBackBody, null, response);
        return response;
    }

    public String processCsOrderLogAndResponse(String channelCode, CommonResult commonResult) {
        // 不同渠道返回信息转换
        String response = extensionExecutor.execute(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(channelCode), ex -> ex.callBackResponse(commonResult));
        String serviceName = channelCode + "_order_cs_callback";
        // 记录请求日志
        // sendRequestMessage(channelCode, providerCode, requestId, serviceName, callBackBody, null, response);
        return response;
    }

    public String processDivideOrderLogAndResponse(String channelCode, CommonResult commonResult) {
        // 不同渠道返回信息转换
        String response = extensionExecutor.execute(ChannelMerchantOrderExtPt.class, BizScenario.valueOf(channelCode), ex -> ex.callBackResponse(commonResult));
        String serviceName = channelCode + "_order_divice_callback";
        // 记录请求日志
        // sendRequestMessage(channelCode, providerCode, requestId, serviceName, callBackBody, null, response);
        return response;
    }

    public void sendRequestMessage(String channelCode, String providerCode, String requestId, String serviceName, String callBackBody, Object thirdParams, String commonResult) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        RequestLogDO requestLogDO = new RequestLogDO();
        requestLogDO.setChannelCode(channelCode);
        requestLogDO.setProviderCode(providerCode);
        requestLogDO.setRequestId(requestId);
        requestLogDO.setRequestUrl(serviceName);
        requestLogDO.setRequestParams(callBackBody);
        if (thirdParams != null) {
            requestLogDO.setParseParams(JsonUtils.toJsonString(thirdParams));
        }
        requestLogDO.setResponse(JsonUtils.toJsonString(commonResult));
        requestLogDO.setIp(ServletUtil.getClientIP(request, null));
        try {
            IpInfo ipInfo = ip2regionProvider.getIp2regionSearcher().memorySearch(requestLogDO.getIp());
            if (ipInfo != null) {
                requestLogDO.setIpLocation(ipInfo.getAddress());
            }
        }
        catch (Exception e) {

        }

        String jsonString = JsonUtils.toJsonString(requestLogDO);
        log.info("sendRequestMessage:{}", jsonString);
        extRocketMQTemplate.send(MqConstant.REQUEST_LOG_TOPIC, requestLogDO);
    }
}
